import asyncio
import json
from concurrent.futures import ThreadPoolExecutor
from fastapi import HTTPException

from common.keyword_extractor import extract_tygjz, extract_zdygjz
from common.threat_extractor import extract_yy
from common.cadre_extractor import extract_sggb_names
from common.category_classifier import classify_xflb
from common.summary_classifier import extract_wtzy, extract_fl
from common.dict_manager import get_dict_name_cached
from letter.letter_logger import log_error
from letter.person_extractor import extract_fyrs, extract_bfyrs


class LetterProcessor:
    """来信件处理核心类"""

    def __init__(self, thread_pool: ThreadPoolExecutor):
        self.thread_pool = thread_pool

    async def async_log_error(self, bh: str, message: str):
        """异步记录错误日志"""
        await asyncio.get_event_loop().run_in_executor(
            self.thread_pool, log_error, bh, message
        )

    async def process_letter_async(self, bh: str, case_content: str, txm: str = ""):
        """
        异步处理来信件的主要函数

        Args:
            bh: 编号
            case_content: 信访件内容
            txm: 条形码

        Returns:
            处理结果字典
        """
        # 文本长度检查和摘要处理已在路由层完成，这里直接使用传入的case_content

        # 初始化返回结果
        result = {
            "bh": bh,
            "txm": txm,  # 添加条形码字段
            "xflb": "",
            "wtxx": {
                "wtzy": "",
                "fl": [],
                "tygjz": [],
                "zdygjz": [],
                "bs": {"yy": "", "sggb": "", "sfcf": ""},
            },
            "fyrs": [],
            "bfyrs": [],
        }

        try:
            # 第一步：并行执行信访分类、基础提取任务和人员信息提取
            print("并行执行信访分类、基础提取任务和人员信息提取...")

            # 创建异步任务列表
            tasks = [
                classify_xflb(case_content),  # 信访分类
                extract_tygjz(case_content),  # 统一关键字提取
                extract_zdygjz(case_content),  # 自定义关键字提取
                extract_yy(case_content),  # 扬言提取
                extract_sggb_names(case_content),  # 省管干部提取
                extract_fyrs(case_content),  # 反映人提取
                extract_bfyrs(case_content),  # 被反映人提取
            ]

            # 添加初次件判重检查任务
            from common.unified_duplicate_checker import check_duplicate_for_letter_case

            tasks.append(check_duplicate_for_letter_case(case_content, bh, ""))

            # 并行执行所有任务
            results = await asyncio.gather(*tasks, return_exceptions=True)

            # 处理信访分类结果
            if isinstance(results[0], tuple) and len(results[0]) == 2:
                raw_xflb, converted_xflb = results[0]
                result["xflb"] = converted_xflb
            else:
                print(f"信访分类失败: {results[0]}")
                result["xflb"] = ""

            # 处理基础提取结果
            self._process_extraction_results(results[1:5], result)

            # 处理反映人结果
            if isinstance(results[5], list):
                result["fyrs"] = results[5]
            else:
                print(f"反映人提取失败: {results[5]}")
                result["fyrs"] = []

            # 处理被反映人结果
            if isinstance(results[6], list):
                result["bfyrs"] = results[6]
            else:
                print(f"被反映人提取失败: {results[6]}")
                result["bfyrs"] = []

            # 处理初次件判重结果
            if isinstance(results[7], str):
                # 检查是否包含重复的编号信息
                if results[7].startswith("1:"):
                    # 格式为 "1:编号"，提取编号
                    duplicate_bh = results[7].split(":", 1)[1]
                    result["wtxx"]["bs"]["sfcf"] = "1"
                    print(f"初次件判重结果: 重复，与编号 {duplicate_bh} 重复")
                else:
                    result["wtxx"]["bs"]["sfcf"] = results[7]
                    print(f"初次件判重结果: {results[7]}")
            else:
                print(f"初次件判重失败: {results[7]}")
                result["wtxx"]["bs"]["sfcf"] = "0"

            # 第二步：根据分类结果进行不同的处理（并行化）
            if isinstance(results[0], tuple) and len(results[0]) == 2:
                raw_xflb, _ = results[0]
                await self._process_classification_based_tasks_parallel(
                    case_content, raw_xflb, result
                )
            else:
                # 如果分类失败，使用默认值
                await self._process_classification_based_tasks_parallel(
                    case_content, "", result
                )

            print("处理完成！")
            return result

        except Exception as e:
            print(f"处理过程中出现错误: {str(e)}")
            await self.async_log_error(bh, f"处理过程中发生错误: {str(e)}")
            raise HTTPException(status_code=500, detail=str(e))

    def _process_extraction_results(self, results, result):
        """处理提取结果"""
        # 处理统一关键字结果
        if isinstance(results[0], str):
            tygjz_result = results[0]
            if tygjz_result:
                result["wtxx"]["tygjz"] = [
                    item.strip() for item in tygjz_result.split(";") if item.strip()
                ]
            else:
                result["wtxx"]["tygjz"] = []

        # 处理自定义关键字结果
        if isinstance(results[1], str):
            zdygjz_result = results[1]
            if zdygjz_result:
                result["wtxx"]["zdygjz"] = [
                    item.strip() for item in zdygjz_result.split(";") if item.strip()
                ]
            else:
                result["wtxx"]["zdygjz"] = []

        # 处理原因结果
        if isinstance(results[2], str):
            yy_result = results[2]
            result["wtxx"]["bs"]["yy"] = (
                "" if yy_result.lower() == "null" else yy_result
            )

        # 处理省管干部结果
        if isinstance(results[3], str):
            sggb_result = results[3]
            result["wtxx"]["bs"]["sggb"] = (
                "" if sggb_result.lower() == "null" else sggb_result
            )

        # 注意：sfcf字段现在由初次件判重结果决定，不再在这里硬编码设置

    async def _process_classification_based_tasks_parallel(
        self, case_content: str, raw_xflb: str, result: dict
    ):
        """根据分类结果处理不同的任务（并行版本）"""
        print("并行进行分类相关任务...")

        # 创建任务列表
        tasks = []

        # 摘要提取：所有类型都需要进行
        tasks.append(extract_wtzy(case_content, raw_xflb))

        # 问题分类：只有检举控告或业务范围外才进行
        if "检举控告" in raw_xflb or "业务范围外" in raw_xflb:
            print("检测到需要问题分类的类型，并行进行问题分类...")
            tasks.append(extract_fl(case_content, raw_xflb))
        else:
            print(f"信访类型 '{raw_xflb}' 不需要进行问题分类，跳过...")
            tasks.append(asyncio.sleep(0))  # 占位任务

        # 并行执行所有任务
        results = await asyncio.gather(*tasks, return_exceptions=True)

        # 处理结果
        # 处理问题总结结果
        if isinstance(results[0], str):
            result["wtxx"]["wtzy"] = results[0]
        else:
            result["wtxx"]["wtzy"] = ""
            print(f"问题总结提取失败: {results[0]}")

        # 处理问题分类结果
        if len(results) > 1 and isinstance(results[1], list):
            print(f"原始问题分类结果: {results[1]}")
            converted_fl = []
            for item in results[1]:
                converted_item = get_dict_name_cached("问题性质", item)
                print(f"问题分类转换: '{item}' -> '{converted_item}'")
                # 只保留转换成功的（非空字符串）
                if converted_item and converted_item.strip():
                    converted_fl.append(converted_item)
            result["wtxx"]["fl"] = converted_fl
            print(f"最终问题分类结果: {result['wtxx']['fl']}")
        elif len(results) > 1 and isinstance(results[1], Exception):
            print(f"问题分类提取失败: {results[1]}")
            result["wtxx"]["fl"] = []
        else:
            result["wtxx"]["fl"] = []
